package com.jplus.plugins.mybatis;

import java.io.File;
import java.io.FileInputStream;
import java.util.List;

import javax.sql.DataSource;

import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jplus.framework.InstanceFactory;
import com.jplus.framework.bean.BeanHandle;
import com.jplus.framework.core.ConfigHandle;
import com.jplus.framework.plugin.Plugin;
import com.jplus.framework.util.FormatUtil;
import com.jplus.plugins.mybatis.proxy.AopMybatisMapper;

/**
 * MybatisPlugin
 * @author Yuanqy
 *
 */
public class MybatisPlugin implements Plugin {
	private Logger logger = LoggerFactory.getLogger(getClass());
	private String daoPkg = ConfigHandle.getString("plugin.mybatis.daoPackage");
	private String xmlPkg = ConfigHandle.getString("plugin.mybatis.xmlPath");
	private Configuration config;
	private static SqlSessionFactory sqlSessionFactory;

	public static SqlSessionFactory getSqlSessionFactory() {
		return sqlSessionFactory;
	}

	@Override
	public void init() {
		if (FormatUtil.isEmpty(daoPkg))
			throw new NullPointerException("The properties value {plugin.mybatis.daoPackage} not found");
		DataSource dataSource = InstanceFactory.getDataSourceFactory().getDataSource();
		TransactionFactory transactionFactory = new JdbcTransactionFactory();// 定义事务工厂
		Environment environment = new Environment("development", transactionFactory, dataSource);
		config = new Configuration(environment);
		// config.setCacheEnabled(true); // 启用缓存
		// config.setLazyLoadingEnabled(false);// 延迟加载
		// config.setAggressiveLazyLoading(false);// 延迟加载
		config.setDefaultStatementTimeout(60);// 数据库响应超时时间
		config.addMappers(daoPkg);// 1.配置dao层
		MapperLocations(config);// 2.配置Mapper.xml
		// Environment en=new Environment(id, transactionFactory, dataSource) ;
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
		{
			// 代理DAO
			List<Class<?>> listDao = InstanceFactory.getClassScanner().getListIsInterface(daoPkg);
			for (Class<?> cla : listDao) {
				Object obj = new AopMybatisMapper<Object>().init(cla);
				BeanHandle.setBean(cla, obj);
				logger.info("\t\t[mybatis-dao]{}", cla);
			}
		}
	}

	@Override
	public void destroy() {
		 
	}

	/**
	 * 扫描xmlMapper
	 * 
	 * @param config
	 */
	private void MapperLocations(Configuration config) {
		try {
			if (FormatUtil.isEmpty(xmlPkg))
				xmlPkg = daoPkg;
			List<File> xmls = InstanceFactory.getClassScanner().getXmlFileList(xmlPkg);
			for (File file : xmls) {
				// System.err.println("\t" + file);
				XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(new FileInputStream(file), config, file.toString(), config.getSqlFragments());
				xmlMapperBuilder.parse();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 添加mybatis插件
	 * 
	 * @param interceptor
	 */
	public <T extends Interceptor> void addPluginElement(T interceptor) {
		config.addInterceptor(interceptor);
	}
}
